<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\ApiController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Question;
use App\Models\User;
use App\Models\Check;
use App\Exceptions\InvalidInputException;
use App\Services\LoginUser;
use App\Models\Exam;

class QuestionsController extends ApiController
{
    private static $fileds = [
        'question_form',
        'question_type',
        // 'graph',
        'ask',
        // 'options',
        'answer',
    ];

    public function __construct(LoginUser $loginUser)
    {
        $this->user = $loginUser->user;
    }

    // /**
    //  * 是否已经处于出题状态
    //  */
    // private function started()
    // {
    //     $session = app('session');
    //     if ($session->has('user')) {
    //         // if ($session->get('status') == 1) {
    //         //     return true;
    //         // }
    //         $id = $session->get('user');
    //         $this->user = User::where('id', $id)->first();
    //         return true;
    //     }
    //     return false;
    // }

    /**
     * @auth(1,2,3)
     */
    public function index(Request $request)
    {
        $all = boolval($request->input('all'));
        $id = $request->input('id');
        $keyword = $request->input('keyword');
        $query = Question::with(['examStatus', 'checkStatus']);
        $this->debug = $keyword;
        if (!$all) {
            $query->where('author_id', $this->user->id);
        }
        if ($id) {
            $query->where('questions.id', $id);
            $this->debug = $id;
        }
        if ($keyword) {
            $query->where('questions.ask', 'LIKE', "%{$keyword}%");
        }
        $data = $query->paginate(10);
        foreach ($data as $item) {
            $exam = Exam::where('question_id', $item->id)->where('subject_id', $this->user->id)->first();
            $flag = $exam ? true : false;
            $item->has_exam = $flag;
        }
        return $this->success($data);
    }

    /**
     * @auth(1,2,3)
     */
    public function store(Request $request)
    {
        $question = new Question();
        // 验证输入
        $valid = $this->checkInput($request);
        if ($valid !== false) {
            return $this->error($valid);
        }
        foreach (static::$fileds as $filed) {
            $question->{$filed} = $request->input($filed);
        }
        $question->options = json_encode($request->input('options'));
        $question->author_id = $this->user->id;
        $question->save();
        return $this->success([
            'id' => $question->id
        ]);
    }

    /**
     * @auth(1,2,3)
     */
    public function show($id)
    {
        return $this->success(
            Question::where('id', $id)->first()
        );
    }

    /**
     * @auth(2,3)
     */
    public function nextCheck(Request $request)
    {
        $userId = $this->user->id;
        // 优先搜索所有人都没审核过的题目
        $result = Db::table('question_statistics')->whereNull('check_num')->orderBy(DB::raw('RAND()'))->first();
        if ($result) {
            $questionId = $result->id;
        } else {
            // 找出自己还没审核过的题目，随机选一个
            $question = Question::leftJoin('checks', function ($join) use ($userId) {
                $join->on('checks.question_id', '=', 'questions.id')
                    ->where('checks.checker_id', '=', $userId);
            })
                ->select('questions.*', DB::raw('SUM(checks.is_pass) AS pass_num, SUM(checks.is_fail) AS fail_num'))
                ->groupBy('questions.id')
                ->havingRaw('pass_num IS NULL')
                ->orderBy(DB::raw('RAND()'))
                ->first();
            $questionId = $question->id;
        }
        // 重新查询以获取实际审核状态
        $question = Question::with(['examStatus', 'checkStatus'])->where('questions.id', $questionId)->first();

        return $question ? $this->success($question) : $this->error('所有的题你都审核过了哦');
    }

    /**
     * @auth(2,3)
     */
    public function check($id, Request $request)
    {
        $check = Check::firstOrNew([
            'question_id' => $id,
            'checker_id' => $this->user->id
        ]);
        if ($request->input('status')) {
            $check->is_pass = 1;
            $check->is_fail = 0;
        } else {
            $check->is_pass = 0;
            $check->is_fail = 1;
        }
        $check->save();
        return $this->success();
    }

    /**
     * @auth(1,2,3)
     */
    public function exam($id, Request $request)
    {
        $exam = Exam::firstOrNew([
            'question_id' => $id,
            'subject_id' => $this->user->id
        ]);
        if ($request->input('status')) {
            $exam->is_pass = 1;
            $exam->is_fail = 0;
        } else {
            $exam->is_pass = 0;
            $exam->is_fail = 1;
        }
        $exam->save();
        return $this->success();
    }

    /**
     * @auth(1,2,3)
     */
    public function update($id, Request $request)
    {
        $question = Question::where('id', $id)->first();
        if ($question === null) {
            return $this->error('没有找到该题目');
        }
        if ($this->user->role == 1) {
            if ($question->author_id != $this->user->id) {
                return $this->error('这不是你出的题目哦');
            }
        }
        // 验证输入
        $valid = $this->checkInput($request);
        if ($valid !== false) {
            return $this->error($valid);
        }
        foreach (static::$fileds as $filed) {
            $question->{$filed} = $request->input($filed);
        }
        $question->options = json_encode($request->input('options'));
        $question->save();
        return $this->success();
    }

    /**
     * @auth(1,2,3)
     */
    public function updateGraph($id, Request $request)
    {
        // 找到题目
        $question = Question::where('id', $id)->first();
        if ($question === null) {
            return $this->error('没有找到该题目');
        }

        // 检查大小
        $graph = $request->file('graph');
        $size = $graph->getSize();
        if ($size / 1024 / 1024 > 2) {
            return $this->error('图片大小不能超过2MB');
        }

        // 检查类型
        $extension = $graph->getClientOriginalExtension();
        $extension = strtolower($extension);
        if (!($extension == 'png' || $extension == 'jpg' || $extension == 'jpeg')) {
            return $this->error('图片必须是png或者jpg格式');
        }

        // 删除旧图片
        $graphDir = storage_path() . '/graphs/';
        if ($question->graph !== null) {
            unlink($graphDir . $question->graph);
        }

        // 移动文件
        $fileName = sprintf('G%04d', intval($id)) . '.' . $extension;
        $graph->move($graphDir, $fileName);

        // 保存文件名
        $question->graph = $fileName;
        $question->save();

        return $this->success();
    }

    /**
     * @auth(1,2,3)
     */
    public function getGraph($id)
    {
        // 找到题目
        $question = Question::where('id', $id)->first();
        if ($question === null) {
            return $this->error('没有找到该题目');
        }
        if ($question->graph === null) {
            return $this->error('该题目没有图片');
        }

        // 返回图片
        $name = $question->graph;
        $graphPath = storage_path() . '/graphs/' . $name;
        if (file_exists($graphPath)) {
            $response = response()->make();
            if (preg_match('/\.png$/', $name)) {
                $response->header('Content-Type', 'image/png');
            } else if (preg_match('/\.jp(e?)g$/', $name)) {
                $response->header('Content-Type', 'image/jpeg');
            }
            $graph = file_get_contents($graphPath);
            $response->setContent($graph);
            return $response;
        } else {
            return $this->error('图片好像消失了！');
        }
    }

    /**
     * @auth(1,2,3)
     */
    public function destory($id)
    {
        $question = Question::where('id', $id)->first();
        if ($this->user->role == 1) {
            if ($question->author_id != $this->user->id) {
                return $this->error('这不是你出的题目哦');
            }
        }
        // 删除图片
        $graphDir = storage_path() . '/graphs/';
        if ($question->graph !== null) {
            $path = $graphDir . $question->graph;
            if (file_exists($path)) {
                @unlink($path);
            }
        }
        $question->delete();
        return $this->success();
    }

    private function checkInput(Request $request)
    {
        try {
            $this->checkField($request->input('ask'), '题目');
            $this->checkField($request->input('answer'), '答案');
            if ($request->input('question_form') == 1) {
                $options = $request->input('options');
                foreach ($options as $option) {
                    $this->checkField($option, '选项');
                }
            }
        } catch (InvalidInputException $e) {
            return $e->getMessage();
        }
        return false;
    }

    private function checkField($str, $name)
    {
        if (preg_match("/\s/", $str)) {
            throw new InvalidInputException($name . '中不能有空格');
        }
        if ($str === '') {
            throw new InvalidInputException($name . '不能为空');
        }
    }
}
